import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';
import { LogMiddleware } from './common/middleware/log.middleware';
// import { CatsController } from './cats/cats.controller';
import { UserModule } from './user/user.module';
import { ConfigModule } from './config/config.module';
import { ListModule } from './list/list.module';
import { UploadModule } from './upload/upload.module';
import { GuardModule } from './guard/guard.module';

@Module({
  // 配置功能模块
  imports: [
    CatsModule,
    UserModule,
    ConfigModule.fooRoot({ path: '/config' }),
    ListModule,
    UploadModule,
    GuardModule,
  ],
  controllers: [AppController],
  // 负责提供共享的变量、方法或对象，以便其他模块或组件可以访问和使用
  // 我们需要向 Nest 注册该服务，以便它可以执行注入
  providers: [
    {
      provide: 'appService', // 自定义service名称, 用的时候需要用到@Inject('appService')注入
      useValue: AppService,
    },
    {
      provide: 'shop', // 自定义注入值
      useValue: ['milk', 'bread', 'butter'],
    },
  ],
  // providers: [AppService], // 简写
})
/**
 * @Module() 装饰器中没有中间件的位置。
 * 相反，我们使用模块类的 configure() 方法设置它们。
 * 包含中间件的模块必须实现 NestModule 接口。
 */
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    // 1.应用中间件
    consumer.apply(LogMiddleware).forRoutes('cats');
    // 2.应用中间件到路由/cats的GET请求
    // apply() 方法可以采用单个中间件或多个参数来指定 多个中间件。
    // consumer
    //   .apply(LogMiddleware)
    //   .forRoutes({ path: 'cats', method: RequestMethod.POST });
    // 3.forRoutes() 方法可以接受单个字符串、多个字符串、一个 RouteInfo 对象、一个控制器类甚至多个控制器类。
    // consumer.apply(LogMiddleware).forRoutes(CatsController);
  }
}
